package game.module.item.logic;

import game.common.response.PrompMsg;
import game.common.response.TipMsg;
import game.constants.GameConstant;
import game.constants.Position;
import game.entity.Hero;
import game.module.item.beans.CharacterGoods;
import game.module.item.beans.Goodmodel;
import game.module.item.dao.GoodsDataEntryManager;
import game.module.item.response.CharacterGetGoods11212;
import game.module.item.response.CharacterLoseGoods11214;
import game.module.item.response.GoodsUpdata10176;
import game.serverenv.GameServerOnlineManager;
import game.util.NetTool;

import java.util.Collection;
import java.util.Map;

import lion.core.SpringContextHolder;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;

@Component
public class BagGoodsContainer extends AbstractGirdContainer implements IBag {
	private static Logger logger = Logger.getLogger(BagGoodsContainer.class);

	@Autowired
	private CacheManager cacheManager;

	@Autowired
	private GoodsDataEntryManager dataEntryManager;

	@Autowired
	private NetTool netTool;

	@Autowired
	private GameServerOnlineManager gameServerOnlineManager;

	public BagGoodsContainer() {
		beginPosition = Position.BagGoodsBeginPostion;
	}

	@Override
	public boolean deleteGoodsByModel(int modelid, int deletecount) {

		if (deletecount <= 0) {
			return false;
		}

		int realcount = getGoodsCountByModelID(modelid);
		if (realcount < deletecount) {
			// TODO 包裹里没有足够的此类物品
			return false;
		}

		int leavecount = deletecount;
		for (CharacterGoods goods : getGoodsMap(1).values()) {
			if (goods.getGoodmodelId() != modelid || goods.isInTrade() || goods.isExpired()) {
				continue;
			}

			if (goods.getCount() > leavecount) {
				// 内存
				goods.setCount(goods.getCount() - leavecount);
				updateFromContainer(goods);
				owner.sendMsg(new CharacterLoseGoods11214(modelid, leavecount));
				if (goods.getBuyType() == 1) {
					// 发送日志
					try {
						long time = 0;
						if (goods.getLastDate() != null) {
							time = goods.getLastDate().getTime() / 1000;
						}
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}
				}
				break;
			} else {
				leavecount = leavecount - goods.getCount();
				deleteGoodsByPostion(goods.getPosition());
				if (goods.getBuyType() == 1) {
					// 发送日志
					try {
						long time = 0;
						if (goods.getLastDate() != null) {
							time = goods.getLastDate().getTime() / 1000;
						}
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}
				}
				if (leavecount == 0) {
					break;
				}
			}
		}

		return true;
	}

	@Override
	public boolean deleteGoodsByModel(int modelid, int deletecount, boolean bind) {
		if (deletecount <= 0) {
			return false;
		}
		int realcount = getGoodsCountByModelID(modelid, bind);
		if (realcount < deletecount) {
			// TODO 包裹里没有足够的此类物品
			return false;
		}

		int leavecount = deletecount;
		for (CharacterGoods goods : getGoodsMap(1).values()) {
			if (goods.getGoodmodelId() != modelid || goods.isInTrade() || goods.isExpired()) {
				continue;
			}

			if (!bind) {
				if (goods.getBind() == 1) {
					continue;
				}
			} else {
				if (goods.getBind() == 0) {
					continue;
				}
			}

			if (goods.getCount() > leavecount) {
				// 内存
				goods.setCount(goods.getCount() - leavecount);
				updateFromContainer(goods);
				owner.sendMsg(new CharacterLoseGoods11214(modelid, leavecount));
				if (goods.getBuyType() == 1) {
					// 发送日志
					try {
						long time = 0;
						if (goods.getLastDate() != null) {
							time = goods.getLastDate().getTime() / 1000;
						}
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}
				}
				break;
			} else {
				leavecount = leavecount - goods.getCount();
				deleteGoodsByPostion(goods.getPosition());
				if (goods.getBuyType() == 1) {
					// 发送日志
					try {
						long time = 0;
						if (goods.getLastDate() != null) {
							time = goods.getLastDate().getTime() / 1000;
						}
					} catch (Exception e) {
						System.err.println(e.getMessage());
					}
				}
				if (leavecount == 0) {
					break;
				}
			}
		}

		return true;
	}

	private void updateFromContainer(CharacterGoods goods) {
		// 消息
		owner.sendMsg(new GoodsUpdata10176(goods));
		// 数据库
		SpringContextHolder.getBean(GoodsDataEntryManager.class).updataCharacterGoods(goods);
	}

	@Override
	public boolean checksuit(CharacterGoods goods) {
		return true;
	}

	// 每次获得新的装备道具时与老的装备进行属性比较，若属性更好则弹出面板提示 每次都触发
	// 属性比较规则：
	// 该道具玩家是否可穿戴，不可穿戴则不弹出提示面板
	// 1： 只与同部位的道具进行比较
	// 2： 原部位上无装备，则新获得的装备属性更好
	// 3： 佩戴等级限制越高，则装备属性越好
	// 4： 佩戴等级限制相同，则品质颜色越高装备属性越好
	// 5： 颜色品质相同，则强化等级越高，属性越好
	// 6： 强化等级相同，则两者属性的好坏判断为相同，不弹出换装提示面板
	@Override
	protected void onChangePositionGoodsAdd(CharacterGoods goods) {

	}

	@Override
	protected void onChangePostionGoodsRemove(CharacterGoods goods) {

		if (goods.getQuickbarindex() != 0) {
			CharacterGoods nextquickbargoods = getFirstGoodsByModelid(goods.getGoodmodelId());
			if (nextquickbargoods != null) {
				// 设置新的快捷栏
				int quickbarindex = goods.getQuickbarindex();
				// owner.getQuickbarController().removeQuickBar(goods.getQuickbarindex());
				// owner.getQuickbarController().removeQuickBarGoods(goods.getQuickbarindex());
				// owner.getQuickbarController().setQuickBarGoods(quickbarindex, nextquickbargoods);
			} else {
				// owner.getQuickbarController().removeQuickBarGoods(goods.getQuickbarindex());
			}
		}
	}

	@Override
	protected void onGoodsRemove(CharacterGoods goods) {
		owner.sendMsg(new CharacterLoseGoods11214(goods.getGoodmodelId(), goods.getCount()));
	}

	@Override
	protected void onGoodsAdd(int heroId, CharacterGoods goods, int totalCount) {
		netTool.sendMsg(heroId, new CharacterGetGoods11212(goods.getGoodmodelId(), totalCount));
		// 检测是否我获得了很好的装备
		// IBody bodygoods = owner.getCharacterGoodController().getBodyGoodsContiner();
		// if (goods.getGoodModel().isEquipment() && bodygoods.checksuit(goods, false)) {
		// CharacterGoods oldgoods = bodygoods.getGoodsByPostion(goods.getGoodModel().getPosition().shortValue());
		// if (oldgoods == null || (oldgoods != null && goods.isBetterEquip(oldgoods))) {
		// owner.sendMsg(new GetABetterEquip50668(goods));
		// }
		// }
		// // 检查是否我获得可学的新技能
		// if (goods.getGoodModel().isSkillBook()) {
		// if (owner.getCharacterSkillManager().isLearnSkill(goods.getGoodModel().getSkill()) == 0) {
		// owner.sendMsg(new GetALearnSkillbook50670(goods));
		// }
		// }
	}

	@Override
	protected void beforeGetGoods(CharacterGoods fromGoods) {
		fromGoods.setInHorseId(0);
	}

	@Override
	public boolean isHasSpaceForAddGoods(Collection<CharacterGoods> goodslist) {
		TempContainer tc = new TempContainer(getGoodsMap(1), beginPosition, getTotalCapacity(1));
		return tc.tryAddGoods(goodslist);
	}

	@Override
	public boolean isHasSpaceForAddGoods(CharacterGoods goods) {
		return isHasEnoughCapacityForAddGoods(goods, getGoodsMap(1), getTotalCapacity(1));
	}

	public boolean addGoods(int heroId, CharacterGoods goods) {
		CharacterGoods returngoods = addAndReturnLast(heroId, goods);
		if (returngoods == null) {
			return false;
		}
		return true;
	}

	public boolean addGoods(int heroId, Collection<CharacterGoods> goodslist) {
		TempContainer tc = new TempContainer(getGoodsMap(1), beginPosition, getTotalCapacity(1));
		if (!tc.tryAddGoods(goodslist)) {
			// 不能添加物品
			return false;
		}
		for (CharacterGoods goods : goodslist) {
			addGoods(heroId, goods);
		}
		return true;
	}

	public boolean isHasSpaceForRemoveAndAddGoods(Collection<CharacterGoods> removepostions, Collection<CharacterGoods> addlist) {

		TempContainer tc = new TempContainer(getGoodsMap(1), beginPosition, getTotalCapacity(1));
		if (removepostions != null) {
			for (CharacterGoods postion : removepostions) {
				if (postion.getPosition() != null && postion.getPosition() != 0) {// 特定位置的删除
					if (postion.getCount() == null || postion.getCount() == 0) {
						tc.deleteByPostion(postion.getPosition());
					} else {// 物品不能删，也要返回false
						boolean isok = tc.deleteSplitGoods(postion.getPosition(), postion.getCount());
						if (!isok) {
							return false;
						}
					}
				} else {
					boolean isok = true;
					if (postion.getGoodModel() == null) {// 找不到物品模型
						logger.error("can not find good type");
						return false;
					}
					if (postion.getBind() == null) {
						isok = tc.deleteGoodsByModel(postion.getGoodmodelId(), postion.getCount());

					} else {
						isok = tc.deleteGoodsByModel(postion.getGoodmodelId(), postion.getCount(), postion.isBinding());
					}
					if (!isok) {
						return false;
					}
				}
			}
		}

		for (CharacterGoods good : addlist) {
			boolean ok = tc.addGoods(good);
			if (!ok) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 绑定优先删除
	 * 
	 * @param removepostions
	 * @param addlist
	 * @return
	 */
	public boolean isHasSpaceForBindFirstRemoveAndAddGoods(Collection<CharacterGoods> removepostions, Collection<CharacterGoods> addlist) {

		TempContainer tc = new TempContainer(getGoodsMap(1), beginPosition, getTotalCapacity(1));
		if (removepostions != null) {
			for (CharacterGoods postion : removepostions) {
				if (postion.getPosition() != null && postion.getPosition() != 0) {// 特定位置的删除
					if (postion.getCount() == getGoodsMap(1).get(postion.getPosition().shortValue()).getCount()) {
						tc.deleteByPostion(postion.getPosition());
					}
				} else {
					// 按数量删除
					// tc.deleteGoodsByModel(postion.getGoodmodelId(),
					// postion.getCount());
					tc.deleteGoodsByModelBindFirst(postion.getGoodmodelId(), postion.getCount());
				}
			}
		}

		for (CharacterGoods good : addlist) {
			boolean ok = tc.addGoods(good);
			if (!ok) {
				return false;
			}
		}
		return true;
	}

	@Override
	public boolean deleteSplitGoods(short oldpostion, int splitcount) {
		CharacterGoods goods = getGoodsMap(1).get(oldpostion);
		if (goods == null) {
			owner.sendMsg(new PrompMsg(TipMsg.MSGPOSITION_ERRORTIP, 754));
			return false;
		}
		if (goods.isInTrade()) {
			owner.sendMsg(new PrompMsg(TipMsg.MSGPOSITION_ERRORTIP, 749));
			return false;
		}
		if (goods.isExpired()) {
			// owner.sendMsg(new PrompMsg(TipMsg.MSGPOSITION_ERRORTIP,749));
			return false;
		}

		if (splitcount <= 0 || splitcount > goods.getCount()) {
			return false;
		}

		if (splitcount == goods.getCount()) {
			deleteGoodsByPostion(oldpostion);
			return true;
		}

		goods.setCount(goods.getCount() - splitcount);
		owner.sendMsg(new GoodsUpdata10176(goods));
		// 数据库
		SpringContextHolder.getBean(GoodsDataEntryManager.class).updateGoodsPositonCount(goods);
		owner.sendMsg(new CharacterLoseGoods11214(goods.getGoodmodelId(), splitcount));
		return true;
	}

	@Override
	public short getSuitPostionForGoods(int heroId, CharacterGoods fromGoods, IContainer fromContainer) {
		short postion = findFirstIdleGirdPosition(heroId);
		if (postion == 0 && fromContainer instanceof IStall) {
			owner.sendMsg(new PrompMsg(TipMsg.MSGPOSITION_ERRORTIP, 755));
		}
		return findFirstIdleGirdPosition(heroId);

	}

	@Override
	public boolean removeAndAddGoods(int heroId, Collection<CharacterGoods> removepostions, Collection<CharacterGoods> addlist) {
		if (!isHasSpaceForRemoveAndAddGoods(removepostions, addlist)) {
			return false;
		}
		if (removepostions != null) {
			for (CharacterGoods postion : removepostions) {
				if (postion.getPosition() != null && postion.getPosition() != 0) {
					if (postion.getCount() == null || postion.getCount() == 0) {// 特定位置的删除,不计数量
						deleteGoodsByPostion(postion.getPosition());
					} else {
						deleteSplitGoods(postion.getPosition(), postion.getCount());
					}
				} else {
					// 按数量删除
					if (postion.getBind() == null) {
						deleteGoodsByModel(postion.getGoodmodelId(), postion.getCount());
					} else {
						deleteGoodsByModel(postion.getGoodmodelId(), postion.getCount(), postion.isBinding());
					}
				}
			}
		}
		for (CharacterGoods good : addlist) {
			boolean ok = addGoods(heroId, good);
			if (!ok) {
				return false;
			}
		}
		return true;
	}

	@Override
	public CharacterGoods getFirstGoodsByModelid(int modelid) {
		for (CharacterGoods goodsInBag : getGoodsMap(1).values()) {
			if (goodsInBag.getGoodmodelId() == modelid) {
				return goodsInBag;
			}
		}
		return null;
	}

	@Override
	public CharacterGoods addAndReturnLast(int heroId, CharacterGoods goods) {
		if (!isHasEnoughCapacityForAddGoods(goods, getGoodsMap(heroId), getTotalCapacity(heroId))) {
			return null;
		}
		int totalCount = goods.getCount();
		Goodmodel goodmodel = goods.getGoodModel();
		try {
			goods = (CharacterGoods) goods.clone();
		} catch (CloneNotSupportedException e) {
			logger.error(e.getMessage(), e);
		}
		int needcount = goods.getCount();
		goods.setCharacterId(heroId);
		// 先尝试在指定位置插入是否可又满足
		short requirePostion = goods.getPosition() == null ? 0 : goods.getPosition();
		if (requirePostion > beginPosition && requirePostion <= beginPosition + getTotalCapacity(heroId)) {
			CharacterGoods oldgoods = getGoodsByPostion(heroId, requirePostion);
			if (oldgoods != null) {
				if (getLeavingsFreeSpace(oldgoods) >= needcount && isMergeAble(oldgoods, goods)) {
					oldgoods.setCount(oldgoods.getCount() + needcount);
					// 消息
					netTool.sendMsg(heroId, new GoodsUpdata10176(oldgoods));
					// 数据库
					dataEntryManager.updateGoodsPositonCount(oldgoods);
					onGoodsAdd(heroId, goods, totalCount);
					return oldgoods;
				}
			} else {
				if (goods.getGoodModel().getRepeat() >= goods.getCount()) {
					// 可以直接放到
					// 内存
					getGoodsMap(heroId).put(requirePostion, goods);
					// 消息
					netTool.sendMsg(heroId, new GoodsUpdata10176(goods));
					// 数据库
					dataEntryManager.insertCharacterGoods(goods);
					onGoodsAdd(heroId, goods, totalCount);
					return goods;
				}

			}
		}

		// 先合并的方式插入
		for (CharacterGoods goodsInBag : getGoodsMap(heroId).values()) {
			if (isMergeAble(goodsInBag, goods)) {// 检查是否可又堆叠
				int leavingspace = getLeavingsFreeSpace(goodsInBag);
				if (leavingspace > 0) {
					if (leavingspace >= needcount) {
						// 内存
						goodsInBag.setCount(goodsInBag.getCount() + needcount);
						// 消息
						netTool.sendMsg(heroId, new GoodsUpdata10176(goodsInBag));
						// 数据库
						dataEntryManager.updateGoodsPositonCount(goodsInBag);
						needcount = 0;
					} else {
						// 内存
						goodsInBag.setCount(goodmodel.getRepeat());
						// 消息
						netTool.sendMsg(heroId, new GoodsUpdata10176(goodsInBag));
						// 数据库
						dataEntryManager.updateGoodsPositonCount(goodsInBag);
						needcount = needcount - leavingspace;
					}
					goods.setPosition(goodsInBag.getPosition());
				}

			}
			if (needcount == 0) {
				break;
			}
		}
		// 再用新空间查入
		while (needcount > 0) {
			short index = findFirstIdleGirdPosition(heroId);
			if (index == 0) {
				break;
			}
			try {
				goods = (CharacterGoods) goods.clone();
				goods.setCharacterId(heroId);
			} catch (CloneNotSupportedException e) {
				logger.error(e.getMessage(), e);
			}
			goods.setPosition(index);
			if (goodmodel.getRepeat() >= needcount) {
				goods.setCount(needcount);
				needcount = 0;
			} else {
				goods.setCount(goodmodel.getRepeat());
				needcount = needcount - goodmodel.getRepeat();
			}
			// 内存
			getGoodsMap(heroId).put(index, goods);
			// 消息
			netTool.sendMsg(heroId, new GoodsUpdata10176(goods));
			// 数据库
			dataEntryManager.insertCharacterGoods(goods);
		}
		onGoodsAdd(heroId, goods, totalCount);
		return goods;
	}

	/**
	 * 交易中验证是否有足够空间
	 * 
	 * @param values
	 * @param goodsCollection
	 * @return
	 */
	@Override
	public boolean isHasSpaceForRemoveAndAddGoodsInTrading(Collection<CharacterGoods> removepostions, Collection<CharacterGoods> addlist) {
		TempContainer tc = new TempContainer(getGoodsMap(1), beginPosition, getTotalCapacity(1), true);
		if (removepostions != null) {
			for (CharacterGoods postion : removepostions) {
				if (postion.getPosition() != null && postion.getPosition() != 0) {// 特定位置的删除
					if (postion.getCount() == null || postion.getCount() == 0) {
						tc.deleteByPostion(postion.getPosition());
					} else {// 物品不能删，也要返回false
						boolean isok = tc.deleteSplitGoods(postion.getPosition(), postion.getCount());
						if (!isok) {
							return false;
						}
					}
				} else {
					// 按数量删除
					boolean isok = tc.deleteGoodsByModel(postion.getGoodmodelId(), postion.getCount());
					if (!isok) {
						return false;
					}
				}

			}
		}
		for (CharacterGoods good : addlist) {
			boolean ok = tc.addGoods(good);
			if (!ok) {
				return false;
			}
		}
		return true;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Map<Short, CharacterGoods> getGoodsMap(int heroId) {
		Cache cache = cacheManager.getCache(GameConstant.CACHE_GOODS);
		return (Map<Short, CharacterGoods>) cache.get(GameConstant.CACHE_GOODS_BAG + heroId).get();
	}

	@Override
	protected void setGoodsMap(Map<Short, CharacterGoods> goods) {

	}

	@Override
	public int getTotalCapacity(int heroId) {
		int capacity = 30;
		Hero hero = gameServerOnlineManager.getByID(heroId);
		if (hero != null) {
			capacity = hero.getBagCapacity();
		}
		return capacity;
	}
}
